package dimensional.traveler.client.screens.gamemenu;

import java.util.Collection;

import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.cell.core.client.ButtonCell.IconAlign;
import com.sencha.gxt.core.client.util.Margins;
import com.sencha.gxt.widget.core.client.ContentPanel;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.container.AccordionLayoutContainer;
import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer.BorderLayoutData;
import com.sencha.gxt.widget.core.client.container.BoxLayoutContainer.BoxLayoutData;
import com.sencha.gxt.widget.core.client.container.VBoxLayoutContainer;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.event.SelectEvent.SelectHandler;

import dimensional.traveler.client.mvc.ControlledComposite;
import dimensional.traveler.client.mvc.MediatedController;
import dimensional.traveler.client.resources.images.Images;
import dimensional.traveler.client.resources.images.icons.system.SystemIcons;
import dimensional.traveler.client.resources.images.icons.universes.UniverseIconFactory;
import dimensional.traveler.shared.model.Describable;
import dimensional.traveler.shared.model.Mission;

public class GameMenuScreen extends ControlledComposite {

	private static GameMenuScreenUiBinder uiBinder = GWT.create(GameMenuScreenUiBinder.class);

	private final class MissionButtonHandler implements SelectHandler {
		@Override
		public void onSelect(SelectEvent event) {
			TextButton source = (TextButton) event.getSource();
			String missionId = source.getData("missionId");
			Mission mission = controller.getNewMissionById(missionId);
			if (mission == null)
				mission = controller.getOldMissionById(missionId);
			updateRightPanelWith(mission);
		}
	}

	interface GameMenuScreenUiBinder extends UiBinder<Widget, GameMenuScreen> {
	}

	@UiField
	ContentPanel activePanel;
	@UiField
	AccordionLayoutContainer container;
	@UiField
	ContentPanel rightPanel;
	
	@UiField
	VBoxLayoutContainer newMissionContainer;
	@UiField
	VBoxLayoutContainer oldMissionContainer;
	@UiField
	VBoxLayoutContainer shopContainer;
	@UiField
	VBoxLayoutContainer trainingContainer;
	@UiField
	VBoxLayoutContainer inventoryContainer;
	
	@UiField(provided = true)
	BorderLayoutData westData = new BorderLayoutData(400);
	@UiField(provided = true)
    Images images = Images.INSTANCE;
	
	@UiField
	TextButton saveButton;
	@UiField
	TextButton saveExitButton;
	@UiField
	TextButton loadButton;
	@UiField
	TextButton exitButton;

	private MissionButtonHandler missionButtonHandler = new MissionButtonHandler();

	private GameMenuController controller = new GameMenuController();
	private UniverseIconFactory eraIconFactory = new UniverseIconFactory();

	public GameMenuScreen() {
		setupBorderLayout();
		initWidget(uiBinder.createAndBindUi(this));
		setupAccordionLayout();
		setupController();
		setupSystemActions();
	}

	private void setupBorderLayout() {
		westData.setSplit(true);
		westData.setCollapsible(true);
	}

	private void setupAccordionLayout() {
		container.setActiveWidget(activePanel);
		setupShops();
		setupTrainers();
		setupInventoryAccess();
	}
	
	private void setupController() {
		controller.setScreen(this);
		this.addAttachHandler(controller);
	}
	
	private void setupSystemActions() {
		saveButton.setIcon(SystemIcons.INSTANCE.save());
		saveExitButton.setIcon(SystemIcons.INSTANCE.saveExit());
		loadButton.setIcon(SystemIcons.INSTANCE.load());
		exitButton.setIcon(SystemIcons.INSTANCE.exit());
	}

	public void setupNewMissions(Collection<Mission> newMissions) {
		insertMissionsIntoContainer(newMissions, newMissionContainer);
		newMissionContainer.forceLayout();
		if (newMissionContainer.getWidgetCount() > 0)
			newMissionContainer.getWidget(0).fireEvent(new SelectEvent());
	}

	public void setupOldMissions(Collection<Mission> oldMissions) {
		insertMissionsIntoContainer(oldMissions, oldMissionContainer);
	}

	private void insertMissionsIntoContainer(Collection<Mission> missions, VBoxLayoutContainer missionContainer) {
		missionContainer.clear();
		if (missions.isEmpty()) {
			missionContainer.add(new Label("No missions available."));
		} else {
			for (Mission mission : missions) {
				missionContainer.add(createMissionButton(mission), new BoxLayoutData(new Margins(4)));
			}
		}
	}

	private Widget createMissionButton(Mission mission) {
		TextButton button = new TextButton();
		button.setText(mission.getShortDescription());
		button.setData("missionId", mission.getMissionId());
		button.setIcon(eraIconFactory.getImageResourceForEra(mission.getEra()));
		button.setIconAlign(IconAlign.LEFT);
		button.addSelectHandler(missionButtonHandler);
		return button;
	}

	private void setupShops() {
		// TODO Auto-generated method stub
		// shopContainer
	}

	private void setupTrainers() {
		// TODO Auto-generated method stub
		// trainingContainer
	}

	private void setupInventoryAccess() {
		// TODO Auto-generated method stub
		// inventoryContainer
	}

	@Override
	public MediatedController getController() {
		return controller;
	}

	@UiHandler("saveButton")
	void handleSave(SelectEvent clickEvent) {
		controller.saveProgress();
	}

	@UiHandler("saveExitButton")
	void handleSaveAndExit(SelectEvent clickEvent) {
		controller.saveProgressAndExit();
	}

	@UiHandler("loadButton")
	void handleLoad(SelectEvent clickEvent) {
		controller.loadGame();
	}

	@UiHandler("exitButton")
	void handleExit(SelectEvent clickEvent) {
		controller.exitGame();
	}

	public void updateRightPanelWith(Describable describable) {
		rightPanel.clear();
		HTML html = new HTML();
		html.setHTML(describable.getShortDescription() + "<br/><br/>" + describable.getLongDescription());
		rightPanel.add(html);
	}

}
